<template>
  <canvas ref="container" id="pandaWalk" class="panda-walk"></canvas>
</template>

<script setup lang="ts">
import * as THREE from "three";
import { onMounted, ref } from "vue";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
const scene = new THREE.Scene();
const container = ref<HTMLCanvasElement>();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
const positions = [
  {
    pos: new THREE.Vector3(-0.3, 0, 1.3),
    rotation: new THREE.Euler(
      -Math.PI / 4,
      Math.PI / 8 + Math.PI / 2 + Math.PI / 16,
      0
    ),
  },
  {
    pos: new THREE.Vector3(0.6, 0, 0),
    rotation: new THREE.Euler(
      -Math.PI / 4,
      Math.PI + Math.PI / 8 + Math.PI / 16,
      0
    ),
  },
  {
    pos: new THREE.Vector3(0.2, 0, -1),
    rotation: new THREE.Euler(
      -Math.PI / 4,
      Math.PI / 8 + Math.PI / 2 + Math.PI / 16,
      0
    ),
  },
  {
    pos: new THREE.Vector3(1.2, 0, -2.2),
    rotation: new THREE.Euler(
      -Math.PI / 4,
      Math.PI / 8 + Math.PI / 2 + Math.PI / 16,
      0
    ),
  },
];
// 相机位置
camera.position.set(0, 5, 0);
const gltfLoader = new GLTFLoader();
const url = "./src/assets/model/panda-walk.gltf";
onMounted(() => {
  const renderer = new THREE.WebGLRenderer({
    canvas: container.value,
    antialias: true,
  });
  renderer.setClearColor(0xfffff, 0);
  renderer.setSize(window.innerWidth, window.innerHeight);
  gltfLoader.load(url, (result) => {
    const model = result.scene;
    // 模型自发光
    model.traverse(function (child) {
      if (child instanceof THREE.Mesh) {
        child.material.emissive = child.material.color;
        child.material.emissiveMap = child.material.map;
      }
    });
    // 模型缩放
    model.scale.set(0.001, 0.001, 0.001);
    model.rotation.set(
      -Math.PI / 4,
      Math.PI / 8 + Math.PI / 2 + Math.PI / 16,
      0
    );
    model.position.set(-0.3, 0, 1.3);
    scene.add(model);
    const mixer = new THREE.AnimationMixer(model);
    // 控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableRotate = false;
    controls.enableZoom = false;
    result.animations.forEach((clip) => {
      mixer.clipAction(clip).play();
    });

    let currentTargetIndex = 0;
    // 动画函数
    function animate() {
      requestAnimationFrame(animate);
      const target = positions[currentTargetIndex];
      const distance = model.position.distanceTo(target.pos);
      if (distance > 0.01) {
        const speed = 0.004;
        const direction = new THREE.Vector3()
          .subVectors(target.pos, model.position)
          .normalize();
        model.position.add(direction.multiplyScalar(speed));
      } else {
        model.rotation.copy(target.rotation);
        if (currentTargetIndex < positions.length - 1) {
          currentTargetIndex++;
        } else {
          model.position.copy(positions[0].pos);
          currentTargetIndex = 0;
        }
      }
      mixer.update(0.02);
      renderer.render(scene, camera);
    }
    animate();
  });
});
</script>

<style lang="scss" scoped>
.panda-walk {
  width: 100vw;
  height: 100vh;
  background: url("@/assets/image/home.png");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}
</style>
